package br.com.imagecropper.cropper;

import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;

public class Cropper {
    public BufferedImage getCroppedImage(HttpServlet servlet, HttpServletRequest request, BufferedImage img) throws IOException {
        // Recuperando parametros do request
        Float imageH = Float.parseFloat(request.getParameter("imageH"));
        Float imageW = Float.parseFloat(request.getParameter("imageW"));
        Float angle = Float.parseFloat(request.getParameter("imageRotate"));
        Float imageX = Float.parseFloat(request.getParameter("imageX"));
        Float imageY = Float.parseFloat(request.getParameter("imageY"));
        Float selectorH = Float.parseFloat(request.getParameter("selectorH"));
        Float selectorW = Float.parseFloat(request.getParameter("selectorW"));
        Float selectorX = Float.parseFloat(request.getParameter("selectorX"));
        Float selectorY = Float.parseFloat(request.getParameter("selectorY"));
        Float viewPortH = Float.parseFloat(request.getParameter("viewPortH"));
        Float viewPortW = Float.parseFloat(request.getParameter("viewPortW"));

        // Redimensionado a imagem
        BufferedImage zoomImg = resizeImageWithHint(img, img.getType(),
                imageW.intValue(), imageH.intValue());

        // Precisamos de uma imagem para o nosso viewport
        BufferedImage viewPortImage = new BufferedImage(viewPortW.intValue(),
                viewPortH.intValue(), BufferedImage.TYPE_4BYTE_ABGR);

        Graphics2D g = viewPortImage.createGraphics();

        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g.setRenderingHint(RenderingHints.KEY_RENDERING,
                RenderingHints.VALUE_RENDER_QUALITY);
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        // Fazemos o translate para funcionar o efeito de drag da imagem
        g.translate(imageX, imageY);
        // Criamos o angulo em cima da imagem
        if (angle > 0.0F && angle < 360.00F) {
            g.rotate(angle * Math.PI / 180.0, zoomImg.getWidth() / 2,
                    zoomImg.getHeight() / 2);
        }

        // Desenhamos a imagem
        g.drawImage(zoomImg, null, 0, 0);

        // Fazemos o crop
        return viewPortImage.getSubimage(
                new Integer(selectorX.intValue()),
                new Integer(selectorY.intValue()),
                new Integer(selectorW.intValue()),
                new Integer(selectorH.intValue()));
    }

    private BufferedImage resizeImageWithHint(BufferedImage img, int type,
            int width, int height) {
        BufferedImage resizedImage = new BufferedImage(width, height, type);
        Graphics2D g = resizedImage.createGraphics();

        g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g.setRenderingHint(RenderingHints.KEY_RENDERING,
                RenderingHints.VALUE_RENDER_QUALITY);
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        g.drawImage(img, 0, 0, width, height, null);
        g.dispose();
        g.setComposite(AlphaComposite.Src);

        return resizedImage;
    }
}
